/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.blue.content;

import java.util.HashMap;
import java.util.Map;


/**
 *
 * @author kelvio.matias
 */
public class ContentManager implements ContentManagerInterface {

    private ContentManager() {
    }

    public static ContentManager getInstance() {
        return ContentManagerHolder.INSTANCE;
    }

    @Override
    public void register(ContentInfo contentInfo) {
        this.contentMap.put(contentInfo.getName(), contentInfo);
    }
        

    private static class ContentManagerHolder {

        private static final ContentManager INSTANCE = new ContentManager();
    }
    private Map<Class<? extends ContentLoader>, Class<? extends ContentLoader>> contentLoaderClassMap = new HashMap<Class<? extends ContentLoader>, Class<? extends ContentLoader>>();
    /**
     *
     */
    private Map<String, Object> contentCacheMap = new HashMap<String, Object>();
    /**
     *
     */
    private Map<String, ContentInfo> contentMap = new HashMap<String, ContentInfo>();
    /**
     *
     */
    private Map<Class<? extends ContentLoader>, ContentLoader> contentLoaderCacheMap = new HashMap<Class<? extends ContentLoader>, ContentLoader>();

    /**
     *
     * @param <T>
     * @param name
     * @return
     */
    @Override
    public <T> T get(String name) {
        if (!this.contentCacheMap.containsKey(name)) {

            if (!this.contentMap.containsKey(name)) {
                throw new ContentNotFoundException("Content not found:" + name);
            }
            this.loadContent(this.contentMap.get(name));

        }
        return (T) this.contentCacheMap.get(name);
    }

    /**
     *
     */
    private void loadContent(ContentInfo content) {
        //Check in content loader cache
        if (!this.contentLoaderCacheMap.containsKey(content.getContentLoaderClass())) {
            this.contentLoaderCacheMap.put(content.getContentLoaderClass(), this.createContentLoader(content.getContentLoaderClass()));
        }
        this.contentCacheMap.put(content.getName(), this.contentLoaderCacheMap.get(content.getContentLoaderClass()).load(content));
    }

    /**
     *
     * @param contentLoaderClass
     * @return
     */
    private ContentLoader createContentLoader(Class<? extends ContentLoader> contentLoaderClass) {
        try {
            return contentLoaderClass.newInstance();
        } catch (Exception exception) {
            throw new RuntimeException(exception);
        }

    }

    public Map<Class<? extends ContentLoader>, Class<? extends ContentLoader>> getContentLoaderClassMap() {
        return contentLoaderClassMap;
    }

    @Override
    public Map<String, ContentInfo> getContentMap() {
        return contentMap;
    }

    public void setContentMap(Map<String, ContentInfo> contentMap) {
        this.contentMap = contentMap;
    }
}
